$.widget("ui.combobox",{
    options:
        source: null
        name: ''
        isDynamic: false
        isMulti: false
        valueSource: null
        values: null

    _create: ->
        if (@options.isMulti && !@options.isDynamic)
            @buildMultiAutocomplete()
            return;
        if (@options.isMulti && @options.isDynamic)
            @buildMultiAutocomplete()
            return;
        if (!@options.isMulti && !@options.isDynamic && @options.source?)
            url = @options.source;
            @options.source = null;
            $.ajax({
                url: url
                dataType: "json"
                success: (data) =>
                    for item in data
                        if item.Selected
                            $(@element).append("<option selected='selected' value='#{ item.Value }'>#{ item.Text }</option>")
                        else
                            $(@element).append("<option value='#{ item.Value }'>#{ item.Text }</option>")
                    @buildSingleAutocomplete()
            })
            return
       
        if (!@options.isMulti && !@options.isDynamic && !source?)
            @buildSingleAutocomplete()
            return

        if (!@options.isMulti && @options.isDynamic)
            @buildSingleAutocomplete()
            return

    destroy: ->
        @wrapper.remove()
        @items.remove()
        @element.show()
        $.Widget.prototype.destroy.call(@)


    buildSingleAutocomplete:->
        that = @
        select = @element.hide()
        if that.options.isDynamic
            select.attr("name","_#{select.attr('name')}")
        selected = select.children(":selected")
        value = if selected.val() then selected.text() else ""
        wrapper = @wrapper = $("<span>").addClass("ui-combobox").insertAfter(select)
        items = @items = $('<div class="multiselect-items"></div>').appendTo(wrapper.parent())
        input = $( "<input>" )
        input.appendTo( wrapper )
        input.val( value )
        input.attr( "title", "" )
        input.addClass('ui-state-default ui-combobox-input')
        input.autocomplete(
                delay: 0,
                minLength: 0,
                source: ( request, response )->
                    if that.options.isDynamic
                        $.get(
                            that.options.source
                            { term: request.term }
                            (data) ->
                                result = []
                                select.children("option").remove()
                                for item in data
                                        select.append("<option value=#{ item.id }>#{ item.value }</option>")
                                        lastOption = select.find("option:last-child")
                                        result.push({
                                            option: lastOption
                                            label: item.label
                                            value: item.value
                                        })
                                response(result)
                        )
                    else
                        matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i")
                        response(select.children("option").not(':disabled').map( ->
                            text = $(@).text()
                            if @value && (!request.term || matcher.test(text))
                                return {
                                    label: text.replace(
                                        new RegExp(
                                            "(?![^&;]+;)(?!<[^<>]*)(" +
                                            $.ui.autocomplete.escapeRegex(request.term) +
                                            ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                        ), "<strong>$1</strong>")
                                    value: text
                                    option: @
                                }
                        ))
                select: (event, ui ) ->
                    ui.item.option.selected = true;
                    that._trigger( "selected", event, {
                        item: ui.item.option
                    });
                    select.closest("fieldset > div").trigger("validate")
                    if that.options.isDynamic
                        ui.item.option.selected = false;
                        currentOption = items.find("input");
                        if currentOption?
                            option = currentOption.closest('select').find("option[value='#{ currentOption.val() }']")
                        currentOption = $(ui.item.option)
                        currentOption.removeAttr('selected')
                        items.html("<input type='hidden' name='#{ select.attr("name").replace("_","") }' value='#{ currentOption.val()}' />")
                        select.val("")


                change: ( event, ui ) ->
                    if ( !ui.item )
                        return that.removeIfInvalid(@, input);
        )
        @addLink(input)
        @modifyImput(input)

        #Set default values
        if (@options.isDynamic && @options.valueSource?)
            $.ajax(
                url:@options.valueSource
                method:"GET"
                dataType:"json"
                success:(value)->
                     if value?
                        items.html("<input type='hidden' name='#{ select.attr("name").replace("_","") }' value='#{ value.Id}' />")
                        input.val(value.Value)
                        return
            )

    buildMultiAutocomplete:->
        that = @
        select = @element.hide()
        selected = select.children(":selected")
        value = if selected.val() then selected.text() else ""
        wrapper = @wrapper = $("<span>").addClass("ui-combobox").insertAfter(select)
        items = @items = $('<ul class="multiselect-items"></ul>').appendTo(wrapper.parent())
        input = $( "<input>" )
        input.appendTo( wrapper )
        input.val( value )
        input.attr( "title", "" )
        input.addClass('ui-state-default ui-combobox-input')
        input.autocomplete(
                delay: 0,
                minLength: 0,
                source: ( request, response )->
                    if that.options.isDynamic
                        $.get(
                            that.options.source
                            { term: request.term }
                            (data) ->
                                result = []
                                select.children("option").remove()
                                for item in data
                                    if items.find("input[value=#{ item.id }]").length == 0
                                        select.append("<option value=#{ item.id }>#{ item.value }</option>")
                                        lastOption = select.find("option:last-child")
                                        result.push({
                                            option: lastOption
                                            label: item.label
                                            value: item.value
                                        })
                                response(result)
                        )
                    else
                        matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i")
                        response(select.children("option").not(':disabled').map( ->
                            text = $(@).text()
                            if @value && (!request.term || matcher.test(text))
                                return {
                                    label: text.replace(
                                        new RegExp(
                                            "(?![^&;]+;)(?!<[^<>]*)(" +
                                            $.ui.autocomplete.escapeRegex(request.term) +
                                            ")(?![^<>]*>)(?![^&;]+;)", "gi"
                                        ), "<strong>$1</strong>")
                                    value: text
                                    option: @
                                }
                        ))
                select: (event, ui ) ->
                    ui.item.option.selected = false
                    #rise onSelect event
                    that._trigger("selected", event, {
                        item: ui.item.option
                    })
                    currentOption = $(ui.item.option)
                    currentOption.attr('disabled', 'disabled')
                    currentOption.removeAttr('selected')
                    items.append(
                        "<li><input type='hidden' name='#{ select.attr("name") }' value='#{ currentOption.val()}' />" +
                            "<span>#{ currentOption.text() }</span><a class='remove no-link' href='#'></a>" +
                        "</li>")
                    $(@).closest("fieldset>div").trigger("validate")
                    items.find('li:last-child').find('a').on('click', (event) ->
                        event.preventDefault()
                        option = currentOption.closest('select').find("option[value='#{ currentOption.val() }']")
                        option.removeAttr('disabled')
                        div = $(@).closest("fieldset>div")
                        $(@).closest('li').remove()
                        $(div).trigger("validate")
                    )

                    return

                change: ( event, ui ) ->
                    if ( !ui.item )
                        return that.removeIfInvalid(@, input);
                close:( event, ui )->
                    select.val("")
                    input.val("")
        )
        @addLink(input)
        @modifyImput(input)

        #Set selected values for first initialize
        if (@options.isMulti && @options.isDynamic && @options.valueSource?)
            $.ajax(
                url:@options.valueSource
                method:"GET"
                dataType:"json"
                success:(values)->
                    _.each(values, (value)->
                        items.append("<li><input type='hidden' style='display: none' name='#{ select.attr("name") }' value='#{ value.Value}' /><span>#{ value.Text }</span><a class='remove no-link' href='#'></a></li>")
                        items.find('li:last-child').find('a').on('click', (event) ->
                            event.preventDefault()                            
                            div = $(@).closest("fieldset>div")
                            $(@).closest('li').remove()
                            $(div).trigger("validate")
                        )
                        return
                    )
                    return
            )
        #Set selected values for first initialize
        if (@options.isMulti && !@options.isDynamic && @options.values?)
           _.each(@options.values, (value)->
                option = select.find("option[value='#{value}']")
                option.attr("disabled","disabled")
                items.append("<li><input type='hidden' style='display: none' name='#{ select.attr("name") }' value='#{value}' /><span>#{ option.text() }</span><a class='remove no-link' href='#'></a></li>")
                option.removeAttr("selected")
                items.find('li:last-child').find('a').on('click', (event) ->
                    event.preventDefault()
                    option = option.closest('select').find("option[value='#{ option.val() }']")
                    option.removeAttr('disabled')                    
                    div = $(@).closest("fieldset>div")
                    $(@).closest('li').remove()
                    $(div).trigger("validate")
                )
           )
           input.val('')


    removeIfInvalid: (element, input) ->
        select = @element.hide()
        value = $(element).val()
        matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex(value) + "$", "i")
        valid = false
        select.children("option").each( ->
            if $(@).text().match(matcher)
                @selected = valid = true
                return false
        )

        if !valid
            # remove invalid value, as it didn't match anything
            $(element)
                .val("")
                .attr("title", value + " didn't match any item")
                .tooltip("open")
            select.val('')
            setTimeout( ->
                input.tooltip("close").attr("title", '')
            , 2500)
            input.data("autocomplete").term = ''
            return false

    addLink:(input)->
        that =this;
        link =$( "<a>" )
        link.attr( "tabIndex", -1 )
        link.attr( "title", "Show All Items" )
        link.tooltip()
        link.appendTo( @wrapper )
        link.button({
                icons: {
                    primary: "ui-icon-triangle-1-s"
                },
                text: false
            })
        link.removeClass( "ui-corner-all" )
        link.addClass( "ui-corner-right ui-combobox-toggle no-link" )
        link.click(()->
                    #close if already visible
                    if ( input.autocomplete( "widget" ).is( ":visible" ) )
                        input.autocomplete( "close" );
                        that.removeIfInvalid( input );
                        return;

                    #work around a bug (likely same cause as #5265)
                    $( this ).blur();
 
                    #pass empty string as value to search for, displaying all results
                    input.autocomplete( "search", "" );
                    input.focus();
                  )

    modifyImput:(input)->
        input.data("autocomplete")._renderItem = (ul, item) ->
            return $("<li>")
                .data("item.autocomplete", item)
                .append("<a>#{ item.label }</a>")
                .appendTo(ul)

        input.tooltip({
                position:
                    of: this.button
                tooltipClass: "ui-state-highlight"
            })
})